﻿using System;
using System.Collections.Generic;
using System.Globalization;
using System.Linq;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.WebControls;
using Medianamik.Core;
using Medianamik.Core.Profile;
using Medianamik.Core.Security;
using Medianamik.Core.Sugar;
using Medianamik.Globalization;
using Medianamik.UI.Blog.Logic;
using Medianamik.UI.Controls;

namespace Medianamik.UI.Blog
{
    public partial class editUser : BaseModuleEditionPage<ProfileNode>
    {
        #region Fields

        protected TextBox ConfirmedPassword;
        protected TextBox Password;
        protected TextBox UserName;
        protected TextBox Email;
        protected CheckBox Approved;
        protected PlaceHolder PasswordAndEmailConfigurations;
        protected Literal SubTitle;
        protected System.Web.UI.WebControls.DropDownList Groups;
        protected CheckBox SendEmail;
        protected PlaceHolder PasswordAutoGeneration;
        protected PlaceHolder PasswordDetails;
        protected PlaceHolder UserNameDatails;
        protected CheckBox AutoGeneratePwd;
        protected RequiredFieldValidator PasswordRequired;
        protected CustomValidator PasswordStrength;

        #endregion

        #region Events

        protected void Page_Load(object sender, EventArgs e)
        {
            InitFields();

            if (!IsPostBack)
            {
                DisplayPageFields();

                Groups.DataSource = BlogGroups.GetGroups();
                Groups.DataBind();
                Groups.Items.Insert(0, new ListItem());

                if (IsEdition)
                {
                    Groups.SelectedValue = GetUserRole(CurrentUser);

                    Email.Text = CurrentUser.Email;

                    Approved.Checked = CurrentUser.IsApproved;
                }
            }
        }

        protected void AutoGeneratePwdCheckedChanged(object sender, EventArgs e)
        {
            ConfirmedPassword.Text = "";
            Password.Text = "";

            PasswordDetails.Visible = !AutoGeneratePwd.Checked;
            PasswordAutoGeneration.Visible = AutoGeneratePwd.Checked;
        }

        protected void UsernameValidate(object sender, ServerValidateEventArgs e)
        {
            e.IsValid = Membership.GetUser(e.Value, false) == null;
        }

        protected void PasswordStrengthValidate(object sender, ServerValidateEventArgs e)
        {
            var password = e.Value;
            var validator = new PasswordValidator(Membership.Provider);
            var result = validator.ValidatePassword(password);

            e.IsValid = result == PasswordValidationResult.Success;
        }

        protected void PasswordCompareValidate(object sender, ServerValidateEventArgs e)
        {
            var password = e.Value;
            var comparePassword = ConfirmedPassword.Text;

            e.IsValid = password.CompareTo(comparePassword) == 0;
        }

        protected override void Save(object sender, EventArgs e)
        {
            if (IsValid)
            {
                var password = AutoGeneratePwd.Checked ? Membership.GeneratePassword(10, 3) : ConfirmedPassword.Text;

                var user = IsEdition ? CurrentUser :
                    Membership.CreateUser(UserName.Text, password, Email.Text);

                user.Email = Email.Text;
                user.IsApproved = Approved.Checked;

                //User
                Membership.UpdateUser(user);

                //Profile
                var profile = MedianamikFormTemplate.GetFormValue(CurrentNode);

                if (IsEdition)
                {
                    if (Password.Text.Trim().Length > 0)
                        ChangeUserPassword(user, Password.Text.Trim());

                    Core.Logging.LogEntryManager.LogUser(user, "User Modified");

                    if (user.UserName == MedianamikContext.Current.MedianamikUser.UserName)
                    {
                        Session["UserCulture"] = profile.UICultureName;
                    }

                    var selectedGroups = Groups.Items.Cast<ListItem>()
                        .Where(i => i.Selected).Select(i => i.Value);

                    var notSelectedGroups = Groups.Items.Cast<ListItem>()
                        .Select(i => i.Value).Except(selectedGroups);

                    Core.Security.Roles.RemoveUserFromGroups(user.UserName, notSelectedGroups.ToArray());
                    Core.Security.Roles.AddUserToGroups(user.UserName, selectedGroups.ToArray());
                }
                else
                {
                    profile.DefaultInstance.Properties["User"].SetValue((Guid)user.ProviderUserKey);

                    Core.Logging.LogEntryManager.LogUser(user, "User Created");

                    var selectedRoles = Groups.Items.Cast<ListItem>()
                        .Where(i => i.Selected).Select(i => i.Value).ToArray();
                    Core.Security.Roles.AddUserToGroups(user.UserName, selectedRoles);
                }

                profile.SerializeProfileNodeProperties();
                NodeManager.SaveNode(profile);

                // Envoi de courriel
                if (SendEmail.Checked)
                {
                    new Core.Mail.MailManager().SendNewUserConfirmationMessage(user,
                        CultureInfo.GetCultureInfo(profile.UICultureName), password, Context);
                }

                Response.Redirect(ReturnURL);
            }
        }

        #endregion

        #region Properties

        private MembershipUser _user;
        protected MembershipUser CurrentUser
        {
            get
            {
                if (_user == null && IsEdition)
                {
                    _user = Membership.GetUser(CurrentNode.UserId);
                }
                return _user;
            }
        }

        protected override string ReturnURL
        {
            get
            {
                return "userList.aspx";
            }
        }

        public override MedianamikFormTemplate MedianamikFormTemplate
        {
            get { return FormTemplate; }
        }

        public override LinkButton SaveButton
        {
            get { return SaveBtn; }
        }

        protected override Guid? ParentNodeId
        {
            get
            {
                return MedianamikModules.SecurityManagement;
            }
        }

        public override Guid? TypeId
        {
            get
            {
                return MedianamikTypes.MedianamikProfile;
            }
        }

        protected override ProfileNode GetCurrentNode()
        {
            return base.GetCurrentNode().DeserializeProfileNodeProperties();
        }

        #endregion

        #region Methods

        private static void ChangeUserPassword(MembershipUser user, string pNewPassword)
        {
            var tempPassword = user.ResetPassword();
            user.ChangePassword(tempPassword, pNewPassword);
        }

        private void DisplayPageFields()
        {
            if (IsEdition)
            {
                SubTitle.Text = CurrentUser.UserName;
                PasswordAndEmailConfigurations.Visible = false;
                UserNameDatails.Visible = false;
                PasswordRequired.Enabled = false;
                PasswordStrength.ValidateEmptyText = false;
                Groups.Enabled = false;
            }
            else
            {
                SubTitle.Text = Translator.Translate("Medianamik_SecurityManagement", "NewUserTitle");
                PasswordAndEmailConfigurations.Visible = true;
                UserNameDatails.Visible = true;
                PasswordRequired.Enabled = true;
                PasswordStrength.ValidateEmptyText = true;
                Groups.Enabled = true;
            }
        }

        private void InitFields()
        {
            ConfirmedPassword = this.MedianamikFormTemplate.FindControlR("ConfirmedPassword") as TextBox;
            Password = this.MedianamikFormTemplate.FindControlR("Password") as TextBox;
            UserName = this.MedianamikFormTemplate.FindControlR("UserName") as TextBox;
            Email = this.MedianamikFormTemplate.FindControlR("Email") as TextBox;
            Approved = this.MedianamikFormTemplate.FindControlR("Approved") as CheckBox;
            PasswordAndEmailConfigurations = this.MedianamikFormTemplate.FindControlR("PasswordAndEmailConfigurations") as PlaceHolder;
            SubTitle = this.MedianamikFormTemplate.FindControlR("SubTitle") as Literal;
            Groups = this.MedianamikFormTemplate.FindControlR("Groups") as System.Web.UI.WebControls.DropDownList;
            SendEmail = this.MedianamikFormTemplate.FindControlR("SendEmail") as CheckBox;
            PasswordDetails = this.MedianamikFormTemplate.FindControlR("PasswordDetails") as PlaceHolder;
            UserNameDatails = this.MedianamikFormTemplate.FindControlR("UserNameDatails") as PlaceHolder;
            AutoGeneratePwd = this.MedianamikFormTemplate.FindControlR("AutoGeneratePwd") as CheckBox;
            PasswordRequired = this.MedianamikFormTemplate.FindControlR("PasswordRequired") as RequiredFieldValidator;
            PasswordStrength = this.MedianamikFormTemplate.FindControlR("PasswordStrength") as CustomValidator;
            PasswordAutoGeneration = this.MedianamikFormTemplate.FindControlR("PasswordAutoGeneration") as PlaceHolder;
        }

        protected string GetUserRole(MembershipUser user)
        {
            return Core.Security.Roles.GetGroupsForUser(user.UserName).Contains("Blogger") ? "Blogger" : "Commentator";
        }

        #endregion
    }
}
